package GUI;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import Control.*;
import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PImage;
import processing.core.PVector;

public class GV {

	public static ArrayList<Shape> shapes;

	public static ArrayList<Shape> shapesSelected;
	public static int lastShapesSelectedSize;
	public static GregorianCalendar dateStart;
	public static GregorianCalendar dateEnd;
	public static GregorianCalendar  dateFirst;
	public static GregorianCalendar dateLast;

	public static GregorianCalendar hourStart;
	public static GregorianCalendar hourEnd;


	//previous date and hour values to avoid useless calculations
	public static GregorianCalendar lastDateStart;
	public static GregorianCalendar lastDateEnd;
	public static GregorianCalendar lastHourStart;
	public static GregorianCalendar lastHourEnd;


	public static LowerPanel lp;
	public static HorizontalScrollBar hoursb;
	public static GraphsArea ga;
	public static TextBox shapeTextBox;
	public static HoursPanel hoursPanel;
	public static ShapesPanel shapesPanel;

	public static PImage play;
	public static PImage pause;
	public static PImage airportIcon;
	public static PImage militaryBaseIcon;
	public static PImage weatherIcon;
	public static PImage meteorIcon;

	public static ArrayList<UFO> ufoToDisplay;
	public static ArrayList<ArrayList<Integrator>> graphPoints;



	static int width=1024;
	static int height=720;
	public static PApplet processing;
	static int backGroundColor = 35;
	static int textColor = 255;
	static int LineColor = 60; 
	static GradientUtils gu;
	static PFont plotFont;
	static PFont plotBoldFont;
	static int timer=0;



	public static float theScale = (float)1.0;
	public static float MIN_SCALE = (float)0.04;
	public static float MAX_SCALE = (float)100.0;
	public static boolean scaleChanged = false;
	public static PVector translation = new PVector((float)0.0,(float)0.0);
	public static float scaleFactor = (float)(-0.05);

	public static PVector visOffset;
	public static PVector visDimensions;

	public static Map mapClass;
	public static int totalMonths=120;
	public static int totalHours=25;

	public static Cluster cluster;
	public static boolean clusterComputerActivated=false;

	public static String[] monthName = {"Jan", "Feb",
		"Mar", "Apr", "May", "Jun", "Jul",
		"Aug", "Sep", "Oct", "Nov",
	"Dec"};


	//	public static String[] monthName = {"January", "February",
	//        "March", "April", "May", "June", "July",
	//        "August", "September", "October", "November",
	//        "December"};

	public static DataClass data;

	public float dt =(float)0.0;
	public static int updateTimer=0;
	public static float delay = 0;

	public static int dateEndIndex;
	public static int dateStartIndex;

	public static int[] colors;
	public static int[] shapeCol;
	public static int[]	categoryCol;
	public static boolean shapeCategoryColor;

	public static ArrayList<Meteor> meteorsToDisplay = new ArrayList<Meteor>();




	public static GregorianCalendar getDateFromMonthNumber(int indexStart){
		if(indexStart <0 || indexStart>=120) System.out.println("getDateFromMonthNumber indexStart out of bound ");
		int year = indexStart/12+2001;
		int month = indexStart%12;		
		return new GregorianCalendar(year, month, 1);
	}

	public static void changeStartDate(GregorianCalendar startDate){
		GV.dateStart = startDate;
	}
	public static void changeEndDate(GregorianCalendar endDate){
		GV.dateEnd = endDate;
	}

	public static void updateUfoToDisplay(){
		if(GV.dateEnd.equals(GV.lastDateEnd) && GV.dateStart.equals(GV.lastDateStart) &&
				GV.hourEnd.equals(GV.lastHourEnd) && GV.hourStart.equals(GV.lastHourStart) && GV.shapesSelected.size()==lastShapesSelectedSize)
			return;

		int t = GV.processing.millis();
		float dt = (float) (t - updateTimer) / (float)1000.0;
		updateTimer = t;

		delay+=1;

		if(delay>2){
			delay=0;

			//set last date values
			GV.lastDateEnd = GV.dateEnd;
			GV.lastDateStart = GV.dateStart;
			GV.lastHourEnd = GV.hourEnd;
			GV.lastHourStart = GV.hourStart;
			lastShapesSelectedSize = GV.shapesSelected.size();


			createUfoToDisplay();
			createGraphs();
			//if(GV.hoursPanel.showMeteorsButton.state)createMeteorsToDispaly();
			createMeteorsToDispaly();
			GV.cluster.createGridData();
			GV.checkTotalData();

		}
	}
	public static void createGraphs(){
		if(GV.hoursPanel.graphButton.state){
			if(GV.ga.airport.state){GV.ga.createAirportGraphPoints(); }
			else if(GV.ga.popDensity.state){ GV.ga.createDensityGraphPoints(); }
			else if(GV.ga.militaryBases.state){ GV.ga.createMilitaryGraphPoints();}
			else if(GV.ga.hours.state){ GV.ga.createHoursGraphPoints(); }
			else if(GV.ga.months.state){ GV.ga.createMonthGraphPoints();}
			else if(GV.ga.weatherStations.state){ GV.ga.createWeatherStationsPoints();}
		}
	}

	//Updates the GV.meteorToDisplay arrayList
	public static void createMeteorsToDispaly(){
		GV.meteorsToDisplay = new ArrayList<Meteor>();

		ArrayList<ArrayList<ArrayList<Meteor>>> meteors = GV.data.getAllMeteors();

		for(int i=GV.dateStartIndex;i<=GV.dateEndIndex;i++){
			for(int k=GV.hourStart.get(Calendar.HOUR_OF_DAY);k<=GV.hourEnd.get(Calendar.HOUR_OF_DAY);k++){
				if(meteors.get(i)!=null)
				if(meteors.get(i).get(k)!=null)
				for(int j=0;j<meteors.get(i).get(k).size();j++){
					GV.meteorsToDisplay.add(meteors.get(i).get(k).get(j));
				}
			}
		}
	}


	//Updates the GV.ufoToDisplay arrayList
	public static void createUfoToDisplay(){
		GV.ufoToDisplay = new ArrayList<UFO>();
		if(GV.shapesSelected.size()>GV.colors.length){GV.shapeCategoryColor=false;}else{GV.shapeCategoryColor=true;}
		//System.out.println(dateStartIndex +" "+dateEndIndex);
		for(int i=0;i<GV.shapesSelected.size();i++){
			int shapeIndex = GV.shapesSelected.get(i).shape.ordinal();
			if(GV.shapeCategoryColor) GV.shapeCol[shapeIndex]=GV.colors[i];
			for(int j=GV.dateStartIndex;j<=GV.dateEndIndex;j++){
				for(int k =GV.hourStart.get(Calendar.HOUR_OF_DAY);k<=GV.hourEnd.get(Calendar.HOUR_OF_DAY);k++){
					ArrayList<ArrayList<ArrayList<UFO>>> shapeList=GV.data.wholeUfos.get(shapeIndex);
					if(shapeList.size()!=0)
					{
						ArrayList<ArrayList<UFO>> uf = GV.data.wholeUfos.get(shapeIndex).get(j);
						if(uf.size()!=0){
							ArrayList<UFO> u = GV.data.wholeUfos.get(shapeIndex).get(j).get(k);
							//if(u.size()!=0){
							for(int l=0;l<GV.data.wholeUfos.get(shapeIndex).get(j).get(k).size();l++){
								GV.ufoToDisplay.add(GV.data.wholeUfos.get(shapeIndex).get(j).get(k).get(l));
							}
							//}
						}
					}


				}
			}
		}

	}

	public static int getColorIndex(int ordinal) {

		int color =GV.shapeCol[ordinal];

		for(int i=0;i<GV.colors.length;i++){
			if(color == GV.colors[i])
				return i;

		}

		return -1;
	}


	public static void checkTotalData(){
		if(GV.dateEndIndex-GV.dateStartIndex>60 && GV.mapClass.map.sc<130 && !GV.hoursPanel.graphButton.state
				&& ! GV.hoursPanel.clusterButton.state){
			GV.hoursPanel.clusterButton.state=true;
			clusterComputerActivated=true;
		}
		else if(GV.dateEndIndex-GV.dateStartIndex>60 && GV.mapClass.map.sc>=130 && !GV.hoursPanel.graphButton.state
				&& GV.hoursPanel.clusterButton.state && GV.clusterComputerActivated){
			GV.hoursPanel.clusterButton.state=false;
			clusterComputerActivated=false;
		}
	}

}
